# coding = utf-8

import math
import sys
import numpy as np


class NavieBayesClassification(object):
    def __init__(self):
        self.c = []
        self.points = []
        self.c_dict = {}
        self.feature = 0
        self.c_list = []

    def load_data(self, path, feature_num=2):
        f = open(path)
        self.feature = feature_num -1
        for line in f.readlines():
            lines = line.strip().split('\t')
            data_tmp = []
            if len(lines) != feature_num:
                continue
            for i in xrange(feature_num):
                data_tmp.append(float(lines[i]))
            self.points.append(data_tmp)
        f.close()

    def print_data(self):
        n = len(self.points)
        for i in xrange(n):
            for tmp in self.points[i]:
                print tmp,
                print"\t",
            print'\n',
        print('ok!\n')

    def form_dict(self):
        m = len(self.points)
        n = len(self.points[0])
        dataset = self.points

        for i in xrange(m):
            ci = dataset[i][n-1]

            if ci not in self.c_dict.keys():
                self.c_dict[ci] = []
                self.c_list.append(ci)
                for j in xrange(n):
                    self.c_dict[ci].append({})

            temp_dict = self.c_dict[ci]

            for k in xrange(n):
                if dataset[i][k] not in temp_dict[k].keys():
                    temp_dict[k][dataset[i][k]] = 1
                else:
                    temp_dict[k][dataset[i][k]] += 1

        print self.c_dict

    def p_x(self, i, check_key, c_num):
        p = 1
        n = len(self.c_dict)
        x_array = self.c_dict[self.c_list[c_num]]
        xi_dict = x_array[i]
        print 'check_key', check_key

        if float(check_key) not in xi_dict:
            mol = 0
        else:
            mol = xi_dict[float(check_key)]
        der = 0
        for k in xi_dict.values():
            der += k
        p = 1.0 * (mol+1) / (der+len(xi_dict))

        print xi_dict
        print 'p', i,  'value:', p
        return p

    def p_c(self, c_num):
        p = 1
        mol = 0.0
        der = 0.0
        for k in self.points:
            if self.c_list[c_num] == k[self.feature]:
                mol += 1
            der += 1

        print 'c_mol', mol
        print 'c_der', der
        p = 1.0 * (mol + 1) / (der + len(self.c_list))
        return p

    def check_classification(self, data):
        self.form_dict()
        n = len(data)
        p_max = -1
        p = 1.0
        if n != self.feature:
            print "input the error CHECK data!"
            return
        for c_num in xrange(len(self.c_list)):
            print "Label:", self.c_list[c_num]
            for i in xrange(n):
                check_key = data[i]
                p *= self.p_x(i, check_key, c_num)

            p *= self.p_c(c_num)
            print 'p_result', p
            if p_max < p:
                c = self.c_list[c_num]
                p_max = p
                print 'p_max', p_max
            p = 1
        return c


if __name__ == "__main__":
    # input sample data
    data_path = "./data/data.txt"
    bayes = NavieBayesClassification()
    bayes.load_data(data_path, 5)
    bayes.print_data()

    ans = bayes.check_classification([1, 3, 1, 100])
    print 'ans', ans







